#include "WGCustomPlot.h"
#include <QMouseEvent>
#include <QCursor>
#include <QDebug>

#include "test2.h"

QCursor WGCustomPlotWidget::gCursor;
static constexpr int PADDING = 6;

WGCustomPlotWidget::WGCustomPlotWidget(QWidget *parent) :
    QCustomPlot(parent),
    mWGCustomPixmap(nullptr)
{
    setMouseTracking(true);
}

void WGCustomPlotWidget::EnableSRMZoom(bool enable){
    if(enable)
    {
        setSelectionRectMode(QCP::srmZoom);
        gCursor = QCursor(Qt::CrossCursor);
        setCursor(gCursor);
    }else
    {
        setSelectionRectMode(QCP::srmNone);
        gCursor = QCursor(Qt::PointingHandCursor);
        setCursor(gCursor);
    }
}

void WGCustomPlotWidget::SetupPixmapItem(QPixmap &pixmap)
{
    // 创建并配置QCPItemPixmap
    if(!mWGCustomPixmap)
    {
        mWGCustomPixmap = new WGCustomPixmap(this);
        mWGCustomPixmap->setPixmap(pixmap);

        ///加载图片并设置区域到右上角
        double width = this->width() / 5.0;
        double height = this->height() / 5.0;
        int x = this->x() + this->width() - 100 - width;
        int y = this->y() + 100;
        ///绘制图片矩形区域，大小固定不受customplot放大缩小影响
        mWGCustomPixmap->topLeft->setType(QCPItemPosition::ptAbsolute);
        mWGCustomPixmap->topLeft->setPixelPosition(QPointF(x, y));
        mWGCustomPixmap->bottomRight->setType(QCPItemPosition::ptAbsolute);
        mWGCustomPixmap->bottomRight->setPixelPosition(QPointF(x + width, y + height));
        mWGCustomPixmap->setScaled(true, Qt::IgnoreAspectRatio /*Qt::KeepAspectRatio*/);//启用缩放并设置边框

        m_RectItem = new QCPItemRect(this);
        m_RectItem->setVisible(true);
        m_RectItem->setPen(QPen(Qt::black, 1, Qt::DashLine));
        m_RectItem->setBrush(Qt::NoBrush);

        // 设置选框位置
        m_RectItem->topLeft->setCoords(xAxis->range().lower, yAxis->range().upper);
        m_RectItem->bottomRight->setCoords(xAxis->range().upper, yAxis->range().lower);

        //添加关联线
        DynamicPixmapBinder *binder = new DynamicPixmapBinder(this);
        binder->addConnection(m_RectItem, mWGCustomPixmap);
        //刷新图表
        this->replot();
    }
}

void WGCustomPlotWidget::mousePressEvent(QMouseEvent *event) {
    if(mWGCustomPixmap && mWGCustomPixmap->startDrag(event))
    {
    }
    else
    {
        QCustomPlot::mousePressEvent(event);
    }
}

void WGCustomPlotWidget::mouseMoveEvent(QMouseEvent *event) {
//    QString pos22 = QString("%1,%2").arg(event->pos().x()).arg(event->pos().y());
//    QToolTip::showText(event->globalPos(), pos22, this);
    if(mWGCustomPixmap && mWGCustomPixmap->moveDrag(event))
    {
    }else
    {
        QCustomPlot::mouseMoveEvent(event);
    }
}

void WGCustomPlotWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if(mWGCustomPixmap && mWGCustomPixmap->isActive())
    {
        mWGCustomPixmap->endDrag(event);
    }else
    {
        QCustomPlot::mouseReleaseEvent(event);
    }
}

WGCustomPixmap::WGCustomPixmap(QCustomPlot *parentPlot) :
    QCPItemPixmap(parentPlot),
    mActive(false)
{
    setPen(QPen(Qt::gray));
    setSelectedPen(QPen(Qt::red));
}

WGCustomPixmap::~WGCustomPixmap()
{

}

bool WGCustomPixmap::startDrag(QMouseEvent *event)
{
    bool ret = false;
    // 检测是否点击到图片项（阈值8像素）
    double dist = this->selectTest(event->pos(), false);
    qDebug() << "dist:" << dist;
    if(dist >= 0 && dist < 8)
    {
        this->setSelected(true);
        mActive = true;
        mRectF = QRectF(this->topLeft->pixelPosition(), this->bottomRight->pixelPosition());
        if(mDirection != Direction::No)
        {
            this->parentPlot()->mouseGrabber();
        }
        mStartPos = event->pos();
        ret = true;
    }else
    {
        this->setSelected(false);
    }
    layer()->replot();
    return ret;
}

bool WGCustomPixmap::moveDrag(QMouseEvent *event)
{
    bool ret = false;
    const QPoint &gloPoint = event->pos();
    const QPointF &pt_lu = this->topLeft->pixelPosition();
    const QPointF &pt_ll = this->bottomLeft->pixelPosition();
    const QPointF &pt_rl = this->bottomRight->pixelPosition();
    if(!mActive)
    {
        mDirection = region(gloPoint, pt_lu, pt_rl);
        mRectF = QRectF(pt_lu, pt_rl);
    }else
    {
        if(mDirection != Direction::No)
        {
            switch(mDirection)
            {//拉伸图片
                case Direction::Left:
                    mouseChange(gloPoint.x(), pt_ll.y() + 1);
                    break;
                case Direction::Right:
                    mouseChange(gloPoint.x(), pt_rl.y() /*+ 1*/);
                    break;
                case Direction::Top:
                    mouseChange(pt_lu.x(), gloPoint.y());
                    break;
                case Direction::Bottom:
                    mouseChange(pt_rl.x() /*+ 1*/, gloPoint.y());
                    break;
                case Direction::LeftTop:
                case Direction::RightTop:
                case Direction::LeftBottom:
                case Direction::RightBottom:
                    mouseChange(gloPoint.x(), gloPoint.y());
                    break;
                default: break;
            }

            if(mDirection == Direction::In)
            {//移动图片
                QPointF delta = event->pos() - mStartPos;//偏移距离
                setPixmapRect(mRectF.topLeft() + delta, mRectF.bottomRight() + delta);
            }
            layer()->replot();
            ret = true;
        }
    }

    return ret;
}

void WGCustomPixmap::endDrag(QMouseEvent *event)
{
    mActive = false;
}

WGCustomPixmap::Direction WGCustomPixmap::region(const QPointF &cursorPos, const QPointF &topLeft, const QPointF &bottomRight)
{
    Direction ret_dir = Direction::No;

    const QPointF &pt_lu = topLeft;
    const QPointF &pt_rl = bottomRight;
    const double x = cursorPos.x();
    const double y = cursorPos.y();

    QCursor cursor;
    if(pt_lu.x() + PADDING >= x && pt_lu.x() <= x && pt_lu.y() + PADDING >= y && pt_lu.y() <= y)
    {
        ret_dir = Direction::LeftTop;
        cursor = QCursor(Qt::SizeFDiagCursor);
    }
    else if(x >= pt_rl.x() - PADDING && x <= pt_rl.x() && y >= pt_rl.y() - PADDING && y <= pt_rl.y())
    {
        ret_dir = Direction::RightBottom;
        cursor = QCursor(Qt::SizeFDiagCursor);
    }
    else if(x <= pt_lu.x() + PADDING && x >= pt_lu.x() && y >= pt_rl.y() - PADDING && y <= pt_rl.y())
    {
        ret_dir = Direction::LeftBottom;
        cursor = QCursor(Qt::SizeBDiagCursor);
    }
    else if(x <= pt_rl.x() && x >= pt_rl.x() - PADDING && y >= pt_lu.y() && y <= pt_lu.y() + PADDING)
    {
        ret_dir = Direction::RightTop;
        cursor = QCursor(Qt::SizeBDiagCursor);
    }
    else if(x <= pt_lu.x() + PADDING && x >= pt_lu.x())
    {
        ret_dir = Direction::Left;
        cursor = QCursor(Qt::SizeHorCursor);
    }
    else if(x <= pt_rl.x() && x >= pt_rl.x() - PADDING)
    {
        ret_dir = Direction::Right;
        cursor = QCursor(Qt::SizeHorCursor);
    }
    else if(y >= pt_lu.y() && y <= pt_lu.y() + PADDING)
    {
        ret_dir = Direction::Top;
        cursor = QCursor(Qt::SizeVerCursor);
    }
    else if(y <= pt_rl.y() && y >= pt_rl.y() - PADDING)
    {
        ret_dir = Direction::Bottom;
        cursor = QCursor(Qt::SizeVerCursor);
    }
    else if(x > pt_lu.x() && x < pt_rl.x() && y > pt_lu.y() && y < pt_rl.y())
    {
        ret_dir = Direction::In;
        cursor = QCursor(Qt::SizeAllCursor);
    }else
    {
        ret_dir = Direction::No;
        cursor = WGCustomPlotWidget::gCursor;
    }

    this->parentPlot()->setCursor(cursor);
    return ret_dir;
}

void WGCustomPixmap::mouseChange(double x, double y)
{
    if(x < 0 || y < 0)
    {
        return;
    }

    QPointF pt;
    switch(mDirection)
    {
        case Direction::No:
        case Direction::In:
            return;
        case Direction::Right:
        case Direction::Bottom:
        case Direction::RightBottom:
            pt = mRectF.topLeft();
            break;
        case Direction::RightTop:
            pt = mRectF.bottomLeft();
            break;
        case Direction::Left:
        case Direction::LeftBottom:
            pt = mRectF.topRight();
            break;
        case Direction::LeftTop:
        case Direction::Top:
            pt = mRectF.bottomRight();
            break;
        default:
            return;
    }

    const double rx = (x >= pt.x()) ? pt.x() : x;
    const double ry = (y >= pt.y()) ? pt.y() : y;
    const double rw = abs(x - pt.x());
    const double rh = abs(y - pt.y());

    mRectF = QRectF(rx, ry, rw, rh);
    setPixmapRect(QPointF(rx, ry), QPointF(rx + rw, ry + rh));
    layer()->replot();
}

void WGCustomPixmap::setPixmapRect(const QPointF &topLeft, const QPointF &bottomRight)
{
    this->topLeft->setType(QCPItemPosition::ptAbsolute);
    this->topLeft->setPixelPosition(topLeft);
    this->bottomRight->setType(QCPItemPosition::ptAbsolute);
    this->bottomRight->setPixelPosition(bottomRight);
}

